import got from "got";
import { pay } from "./pay.js";
import { coverPayLink } from "./payLink.js";
import config from "../config.js";
import { cookieJar } from "./cookie.js";
import { sleep, log, logError } from "./util.js";

export const applePay = async (order) => {
  await got({
    url: `${config.baseUrl}/api/AutoPay/ApplyPay`,
    method: "POST",
    searchParams: {
      orderId: order.OrderId,
      pickUpId: order.PickUpId,
      deviceName: config.deviceId,
    },
  });
};

export const updatePayStatus = async (order) => {
  await got({
    url: `${config.baseUrl}/api/mop/AutoUpdatePckUP`,
    method: "POST",
    searchParams: {
      orderId: order.OrderId,
      pickUpId: order.PickUpId,
    },
  });
};

export const pushMessage = async (message) => {
  const ids = ["S01202407120560", "S01202211072505"];
  message = config.deviceId + "," + message;
  await Promise.all(
    ids.map(async (id) => {
      await got({
        url: "http://iot.solomo-info.com:9306/admin/common/msgpush",
        method: "POST",
        json: {
          sbx_id: id,
          msg: message,
          msg_token: "",
          agent_id: "202012080010",
          agent_secret: "11476900311497700311476900329001",
          debug: 0,
        },
      });
    }),
  );
};

export const pushBarkMessage = async (message, order) => {
  let url = "";
  message = config.deviceId + "," + message;
  try {
    const payUrl = await coverPayLink(order.PayBiz);
    const u = new URL(payUrl);
    const contextId = u.searchParams.get("session");
    url = `alipay://alipayclient/?%7B%22requestType%22%3A%22SafePay%22%2C%22fromAppUrlScheme%22%3A%22alipays%22%2C%22dataString%22%3A%22h5_route_token%3D%5C%22${contextId}%5C%22%26is_h5_route%3D%5C%22true%5C%22%22%7D`;
  } catch (e) {
    logError(e);
  }
  const content = encodeURIComponent(order.PayBiz);
  log("推送bark", `message: ${message}`, `content: ${content}`);
  await got({
    url: `https://api.day.app/enwhFheR6WoaNaxtS9QX2E/${message}/${content}`, // zzg
    searchParams: { copy: content, level: "critical", volume: 5, url },
  });
};

let lastPayUrl = "";
let lastCookieTime = 0;

const refreshCookie = async () => {
  if (lastPayUrl) {
    await got({
      url: lastPayUrl,
      headers: {
        Referer: lastPayUrl,
        "User-Agent": config.userAgent,
      },
      cookieJar,
    }).catch((err) => logError("payUrl 保活", err.message));
  }
  await got({
    url: "https://mclient.alipay.com/index.htm",
    headers: {
      Referer: "https://mclient.alipay.com/index.htm",
      "User-Agent": config.userAgent,
    },
    cookieJar,
  }).catch((err) => logError("index 保活", err.message));
};

const payOrders = async () => {
  const res = await got({
    url: `${config.baseUrl}/api/AutoPay/GetWaitPayOrderList`,
    searchParams: {
      deviceName: config.deviceId,
      deviceId: config.deviceId,
      orderBy: "asc",
    },
  });
  const body = JSON.parse(res.body);
  const orders = body?.Data || [];
  log(`获取到${orders.length}条订单`);
  if (orders.length > 0) {
    for (const order of orders) {
      const logPrefixes = `${order.MopId},${order.OrderId},`;
      try {
        log(`${logPrefixes}申请支付`);
        applePay(order).catch((e) => logError("申请支付失败", e));

        const payUrl = await coverPayLink(order.PayBiz);
        log(`${logPrefixes}支付地址:${payUrl}`);

        log(`${logPrefixes}开始支付`);
        await pay(payUrl, config.payPwd);
        log(`${logPrefixes}支付成功`);
        lastPayUrl = payUrl;
        lastCookieTime = Date.now();

        updatePayStatus(order).catch((e) => logError("更新支付状态失败", e));
      } catch (err) {
        logError(`${logPrefixes}失败`, err);
        const errMsg = err.message || "";

        pushBarkMessage(`${logPrefixes},${errMsg}`, order).catch((e) =>
          logError("推送bark失败", e),
        );

        pushMessage(errMsg).catch((e) => logError("音响消息推送失败", e));

        if (errMsg.includes("超时")) {
          cookieJar.removeAllCookiesSync();
          log(`cookie失效，已清空，请重新登录`);
        }

        if (
          errMsg.includes("超时") ||
          errMsg.includes("支付密码不正确") ||
          errMsg.includes("验证码")
        ) {
          // 防止消息未推送程序终止
          await sleep(3000);
          process.exit(1);
        }
      } finally {
        await sleep(500);
      }
    }
  } else {
    // 请求支付宝网页防止长时间token失效
    const needRefreshCookie = Date.now() - lastCookieTime > 60 * 1000;
    if (needRefreshCookie) {
      await refreshCookie();
      lastCookieTime = Date.now();
      log("cookie保活执行");
    }
  }
};

export const pollPay = async () => {
  while (true) {
    try {
      await payOrders();
    } catch (e) {
      log(e);
    } finally {
      await sleep(1500);
    }
  }
};
